import {
  audience_exit,
  audience_info,
  audience_join,
  broadcast_info,
  uuid_token,
} from '@/services/broadcast';
import { ProForm, ProFormSelect } from '@ant-design/pro-components';
import { useModel } from '@umijs/max';
import AgoraRTC from 'agora-rtc-sdk-ng';
import AgoraRTM from 'agora-rtm-sdk';
import { Button, Divider, message as M, message, Modal } from 'antd';
import TextArea from 'antd/es/input/TextArea';
import { useEffect, useState } from 'react';
import './index.less';

var RTCclient: any;
var RTMclient: any;
var RTMchannel: any;
// 用来放置本地音视频频轨道对象
var localAudioTrack: any;
var localVideoTrack: any;
// 屏幕共享音频视频轨道对象
var ScreenAudioTrack = null;
var ScreenVideoTrack = null;
// 频道名称
var channel = '';
var uuid_token_data: any;
// 在线用户列表
var list: any[] = [];
// 观众入场纪录id
var audienceJoinId: any;
// 上麦状态
var pulishStatus = false;

var publish_number = 0;
const options = {
  appId: '268a993cd77249cf9f3c1e09a279e96c',
};

const videoConfig: any = {
  // 预设分辨率 默认 480p_1
  encoderConfig: '720p_1',
  // cameraId: 'f74c59fa87dd3bfeed1cce488687f16d3a178e152963a9ee14db5f7b5ff19bdd',
};
const Broadcast_audience_index = () => {
  // 获取URL参数
  const getUrlParam = (name: string) => {
    const reg = new RegExp(`(^|&)${name}=([^&]*)(&|$)`);
    const r = window.location.search.substr(1).match(reg);
    if (r != null) {
      return decodeURIComponent(r[2]);
    }
    return null;
  };
  // 存储当前直播id
  const broadcastId: any = getUrlParam('id');
  // 当前用户详情
  const { initialState, setInitialState } = useModel('@@initialState');
  // 存储直播详情
  const [broadcastinfo, setbroadcastinfo] = useState<any>(undefined);
  // 摄像头列表
  const [camera, setCamera] = useState<any>([]);
  // 控制摄像设备下拉框显示与隐藏
  const [isShowSelect, setIsShowSelect] = useState(false);
  // 控制摄像头的关闭与开启状态
  const [videostatus, setVideostatus] = useState(true);
  // 控制摄像头高亮状态
  const [videoColor, setVideoColor] = useState(false);
  // 控制麦克风的关闭与开启状态
  const [audiostatus, setAudiostatus] = useState(true);
  // 控制麦克风高亮状态
  const [audioColor, setAudioColor] = useState(false);
  // 存储互动人员列表
  const [actionList, setActionList] = useState<any>([]);
  // 存储在线用户列表
  const [audienceList, setAudienceList] = useState<any>([]);
  // 存储消息
  const [chatMessage, setChatMessage] = useState('');
  // 存储聊天列表
  const [chatList, setChatList] = useState([]);
  // 观众入场记录id
  const [JoinId, setJoinId] = useState();
  // 控制底部摄像头以及麦克风按钮的显示与隐藏
  const [video_btn, setVideo_btn] = useState(false);
  // 上麦确认模态框
  const [upStatus, setUpStatus] = useState(false);
  // 摄像设备信息
  const [cameraValue, setCameraValue] = useState<any>();
  // 页面初始化
  useEffect(() => {
    const fetchData = async () => {
      // 获取聊天记录
      setChatList(JSON.parse(localStorage.getItem('chatMessage') || '[]'));
      // 获取互动观众列表
      setActionList(JSON.parse(localStorage.getItem('action') || '[]'));
      // 获取摄像头列表
      getCameras();
      // 加入直播间
      join_broadcast();
    };
    fetchData();
  }, []);

  // 监听页面刷新或关闭
  useEffect(() => {
    window.addEventListener('beforeunload', reload);
    return () => {
      window.removeEventListener('beforeunload', reload);
      // reload();
    };
  }, []);
  const reload = async () => {
    //页面刷新/退出处理
    localStorage.removeItem('action');
    localStorage.removeItem('chatMessage');
    if (RTMchannel) {
      RTMclient.logout();
    }
    await audience_exit({ id: audienceJoinId });
  };
  // 观众入场记录
  const get_audience_join = async () => {
    let audienceJoin: any = await audience_join({ broadcast_id: broadcastId });
    console.log('观众入场记录', audienceJoin);
    if (audienceJoin.msg == 'ok') {
      // setJoinId(audienceJoin.data.id);
      audienceJoinId = audienceJoin.data.id;
    } else {
      message.error(audienceJoin.msg);
    }
  };

  // 获取摄像头列表
  const getCameras = async () => {
    var cameras = await AgoraRTC.getCameras();
    console.log('cameras', cameras);
    let newCamera: any = [];
    cameras.map((item: any) => {
      let temp: any = {};
      temp.value = item.deviceId;
      temp.label = item.label;
      newCamera.push(temp);
    });
    setCamera(newCamera);
    console.log('gjhgjk', newCamera);

    return newCamera;
  };

  //获取直播信息 获取uuid和channel 加入直播间
  const join_broadcast = async () => {
    // 入场记录
    get_audience_join();
    // 获取直播信息
    let info_request_body = {
      id: broadcastId,
    };
    let res: any = await broadcast_info(info_request_body);
    console.log('直播详情', res);
    if (res.msg == 'ok') {
      setbroadcastinfo(res.data);
      channel = res.data.channel;
    } else {
      return;
    }
    //获取uuid和token
    console.log('jjj');
    let uuid_request_body = {
      user_id: initialState?.currentUser?.id,
      origin: 2,
      channel: res.data.channel,
    };
    let params: any = await uuid_token(uuid_request_body);
    if (params.msg == 'ok') {
      uuid_token_data = params.data;
      console.log('uuid', params.data);
      // 加入直播间
      RTCclient = AgoraRTC.createClient({ mode: 'live', codec: 'vp8' });
      RTCclient.setClientRole('audience');
      RTCclient.on('user-published', async (user: any, mediaType: any) => {
        // setPublish(true);

        await RTCclient.subscribe(user, mediaType);
        console.log('user-published', user, mediaType);
        //   判断是主播还是互动观众
        if (user.uid === res.data.uuid) {
          if (mediaType == 'video') {
            // 订阅完成后，从 `user` 中获取远端视频轨道对象
            const remoteVideoTrack = user.videoTrack;
            // 动态插入一个 DIV 节点作为播放远端视频轨道的容器
            // playerContainer = document.getElementById('audience');
            // 订阅完成，播放远端音视频
            // 传入 DIV 节点，让 SDK 在这个节点下创建相应的播放器播放远端视频
            remoteVideoTrack.play(document.getElementById('host'), {
              mirror: false,
              fit: 'contain',
            });
          }
          if (mediaType == 'audio') {
            // 订阅完成后，从 `user` 中获取远端音频轨道对象
            const remoteAudioTrack = user.audioTrack;
            console.log('audio', remoteAudioTrack);
            // 播放音频因为不会有画面，不需要提供 DOM 元素的信息
            remoteAudioTrack.play();
          }
        } else {
          if (mediaType == 'video') {
            publish_number++;
          }

          if (mediaType == 'video') {
            // 订阅完成后，从 `user` 中获取远端视频轨道对象
            const remoteVideoTrack = user.videoTrack;
            // 分屏
            // 动态插入一个 DIV 节点作为播放远端视频轨道的容器
            // playerContainer = document.getElementById('audience');
            // 订阅完成，播放远端音视频
            // 传入 DIV 节点，让 SDK 在这个节点下创建相应的播放器播放远端视频
            remoteVideoTrack.play(document.getElementById('audience'), {
              mirror: false,
              fit: 'contain',
            });
          }
          if (mediaType == 'audio') {
            // 订阅完成后，从 `user` 中获取远端音频轨道对象
            const remoteAudioTrack = user.audioTrack;
            console.log('audio', remoteAudioTrack);
            // 播放音频因为不会有画面，不需要提供 DOM 元素的信息
            remoteAudioTrack.play();
          }
        }
        videoSplit();
      });
      RTCclient.on('user-unpublished', async (user: any, mediaType: any) => {
        if (user.uid != res.data.uuid && mediaType == 'video') {
          publish_number--;
        }
        console.log('user-unpublished', user, mediaType);
        videoSplit();
        // 远端用户取消发布或离开频道
        const playerContainer = document.getElementById('audience');
        console.log('jjjjjjjj', playerContainer?.children);
        if (mediaType === 'video') {
          // 获取刚刚动态创建的 DIV 节点
          // const playerContainer: any = document.getElementById('audience');
        }
      });
      RTCclient.join(options.appId, channel, params.data.rtctoken, params.data.uuid);
      join(params.data.uuid, params.data.rtmtoken, channel);
    } else {
      M.error(params.msg);
    }
  };
  // 控制中间视频区域的分屏状态
  const videoSplit = () => {
    //获取host下的dom数量
    let host_video_num: number = document.getElementById('host')?.children.length ?? 0;
    //获取audience下的dom数量
    let audience_video_num: number = document.getElementById('audience')?.children.length ?? 0;
    //如果 两个都至少有一个，则分屏，反之不分屏
    console.log('publish', publish_number);

    if (host_video_num > 0 && audience_video_num > 0 && publish_number > 0) {
      let audience: any = document.getElementById('audience');
      audience.style.flex = 1;
    } else {
      let audience: any = document.getElementById('audience');
      audience.style.flex = 0;
    }
  };

  // 加入RTM频道
  const join = async (uuid: number, rtmtoken: string, channel: string) => {
    console.log(uuid, rtmtoken, channel);
    RTMclient = AgoraRTM.createInstance(options.appId);
    console.log('RTMclient', RTMclient);
    await RTMclient.login({ uid: uuid.toString(), token: rtmtoken });
    RTMchannel = RTMclient.createChannel(channel);
    console.log('Rtm', RTMchannel);
    await RTMchannel.join();
    // //进入频道后，查询当前频道全部用户
    const nowAudiencelist = await RTMchannel.getMembers();
    console.log('当前频道全部用户', nowAudiencelist);
    nowAudiencelist.forEach((e: number) => {
      joinChannel(e);
    });
    // 监听用户加入频道
    RTMchannel.on('MemberJoined', (memberId: any) => {
      console.log('MemberJoined:' + memberId);
      // 发送当前互动观众信息(点对点消息)
      joinChannel(memberId);
    });
    // 监听用户离开频道
    RTMchannel.on('MemberLeft', (memberId: any) => {
      console.log('MemberLeft:' + memberId);
      leaveChannel(memberId);
    });
    // 频道消息
    RTMchannel.on('ChannelMessage', async (message: any, memberId: any) => {
      console.log('messsage: ', message, ', memberId: ', memberId);
      get_message(JSON.parse(message.text), memberId);
    });
    // 点对点消息，用来处理连麦生命周期 ， 接收挂断通知
    RTMclient.on('MessageFromPeer', async (message: any, peerId: any) => {
      // console.log(message);
      console.log('message ', message, ' peerId', peerId);
      if (JSON.parse(message.text).type === 'shangmai') {
        M.warning('主播邀请你上麦！');
        setUpStatus(true);
        // start_broadcast();
      } else if (JSON.parse(message.text).type === 'xiamai') {
        M.warning('主播取消与你连麦！');
        setUpStatus(false);
        end_broadcast();
      } else if (JSON.parse(message.text).type === 'personChange') {
        console.log('互动观众列表', JSON.parse(message.text));
        let nowAction = JSON.parse(message.text).data;
        nowAction.map((item: any) => {
          // console.log('nowAudiencelist', nowAudiencelist);
          if (nowAudiencelist.some((i: any) => i == item.uuid)) {
            item['actionStatus'] = 1;
          } else {
            item['actionStatus'] = 0;
          }
        });
        // console.log('nowAction', nowAction);
        setActionList(nowAction);
        localStorage.setItem('action', JSON.stringify(nowAction));
      }
    });
  };
  // 观众列表监听
  useEffect(() => {
    list = [...audienceList];
  }, [audienceList.length]);
  // 用户加入频道
  const joinChannel = async (audienceId: number) => {
    setAudienceList(() => {
      list.push(audienceId);
      return [...list] as never[];
    });
    //判断观众是否在互动池里，如果在，则修改对应的在线状态以及连麦状态
    var actionList = JSON.parse(localStorage.getItem('action') || '[]');
    if (Array.from(actionList).some((item: any) => item.uuid == audienceId)) {
      // 修改互动观众在线状态
      changeActionUserStatus(audienceId, 1);
    }
  };

  // 用户离开频道
  const leaveChannel = (audienceId: number) => {
    //判断观众是否在互动池里，如果在，则修改对应的在线状态
    var actionList = JSON.parse(localStorage.getItem('action') || '[]');
    if (Array.from(actionList).some((item: any) => item.uuid == audienceId)) {
      // 修改互动观众在线状态
      changeActionUserStatus(audienceId, 0);
    }
    // 更新观众列表，移除当前观众
    setAudienceList((audienceList: any) => {
      let newList = audienceList.filter((item: any) => item != audienceId);
      return newList;
    });
  };

  //修改互动观众在线状态
  const changeActionUserStatus = (memberId: number, status: number) => {
    setActionList((actionList: any) => {
      let newList = actionList;
      newList.map((item: { uuid: number; actionStatus: number }) => {
        if (item.uuid == memberId) {
          item['actionStatus'] = status;
        }
      });
      localStorage.setItem('action', JSON.stringify([...newList]));
      return [...newList];
    });
  };

  // 上麦
  const start_broadcast = async (value: any) => {
    // console.log('gjhdsgfkj', value);
    videoConfig.cameraId = value.camera;
    RTCclient.setClientRole('host');
    // 加入频道并且推流
    localAudioTrack = await AgoraRTC.createMicrophoneAudioTrack();
    localVideoTrack = await AgoraRTC.createCameraVideoTrack(videoConfig);
    await RTCclient.publish([localAudioTrack, localVideoTrack]);
    localVideoTrack.play(document.getElementById('audience'), { mirror: false, fit: 'contain' });
    setUpStatus(false);
    publish_number++;
    videoSplit();
  };
  // 下麦
  const end_broadcast = () => {
    // console.log('下麦');
    if (RTCclient) {
      RTCclient.unpublish().then(() => {
        if (localAudioTrack) localAudioTrack.close();
        if (localVideoTrack) localVideoTrack.close();
        console.log('hhhhh', document.getElementById('audience')?.children.length);
        // if (document.getElementById('audience')?.children.length === 0) {
        publish_number == 0 ? 0 : publish_number--;
        videoSplit();
        // }
        RTCclient.setClientRole('audience');
      });
    }
  };
  // 聊天框的onChange事件
  const onChange = (e: React.ChangeEvent<HTMLInputElement | HTMLTextAreaElement>) => {
    console.log('Change:', e.target.value);
    setChatMessage(e.target.value);
  };
  // 发送聊天消息(频道消息)
  const sendChatMessage = () => {
    // 发送频道消息
    if (chatMessage.replace(/^\s\s*/, '').replace(/\s\s*$/, '') !== '') {
      RTMchannel.sendMessage({
        text: JSON.stringify({
          type: 'message',
          text: chatMessage,
        }),
      });
      setChatList((chatList) => {
        localStorage.setItem(
          'chatMessage',
          JSON.stringify([
            ...chatList,
            ...[
              {
                type: 'message',
                head_img: initialState?.currentUser?.head_img,
                username: initialState?.currentUser?.username,
                uuid: broadcastinfo.uuid,
                text: chatMessage,
              },
            ],
          ]),
        );
        return [
          ...chatList,
          ...[
            {
              type: 'message',
              head_img: initialState?.currentUser?.head_img,
              username: initialState?.currentUser?.username,
              uuid: broadcastinfo.uuid,
              text: chatMessage,
            },
          ],
        ] as never[];
      });
      // 清空聊天框
      setChatMessage('');
    } else {
      message.error('请输入内容后再发送！');
    }
  };
  // 接收消息
  const get_message = async (message: any, memberId: number) => {
    console.log('频道消息', message);
    if (message.type === 'personChange') {
      let nowAction = message.data;
      nowAction.map((item: any) => {
        console.log('nowAudiencelist', list);
        if (list.some((i: any) => i == item.uuid)) {
          item['actionStatus'] = 1;
        } else {
          item['actionStatus'] = 0;
        }
      });
      setActionList(() => {
        return [...nowAction];
      });
      localStorage.setItem('action', JSON.stringify([...nowAction]));
    }
    if (message.type === 'message') {
      let info: any = await audience_info({ id: memberId });
      console.log('当前观众详情', info);
      let chat: any = [];
      chat.push({
        head_img: info.data.head_img,
        username: info.data.username,
        text: message.text,
      });
      setChatList((chatList) => {
        localStorage.setItem('chatMessage', JSON.stringify([...chatList, ...chat]));
        return [...chatList, ...chat] as never[];
      });
    }
    if (message.type === 'broadcast_end_%fJ9DG#L') {
      M.info('直播已结束！');
      // console.log('HHHH', audienceJoinId);
      await audience_exit({ id: audienceJoinId });
      leave_Live();
    }
  };

  // 始终滚动到最底部
  useEffect(() => {
    updateScroll();
  }, [chatList]);
  const updateScroll = () => {
    var element = document.getElementById('chatList');
    if (element) {
      element.scrollTop = element.scrollHeight;
    }
  };
  // 离开直播间
  const leave_Live = async () => {
    // 离场记录
    await audience_exit({ id: audienceJoinId });
    // 退出RTM频道
    if (RTMclient) {
      RTMclient.logout();
    }
    // // 停止发布（离开频道会自动停止发布）
    if (RTCclient) {
      await RTCclient.unpublish();
      // 退出直播间。
      await RTCclient.leave();
      RTCclient = null;
    }
    // 销毁本地音视频轨道。
    if (localAudioTrack) {
      localAudioTrack.close();
    }
    if (localVideoTrack) {
      localVideoTrack.close();
    }
    localStorage.removeItem('action');
    localStorage.removeItem('chatMessage');
    message.success('已退出直播间！');
    setTimeout(() => {
      window.close();
    }, 2000);
  };
  return (
    <div className="broadcast_index">
      <div className="header">
        {broadcastinfo === undefined ? (
          ''
        ) : (
          <>
            <div className="title">{broadcastinfo.name}</div>
            <div className="name">
              <span>
                主讲医生：{`${broadcastinfo.user_name}(${broadcastinfo.positional_name})`}
              </span>
            </div>
          </>
        )}
        <div className="header_btn">
          <Button onClick={() => leave_Live()}>返回</Button>
        </div>
      </div>
      <div className="content">
        <div className="content_video">
          <div className="video">
            <div id="host" style={{ height: '100%', flex: 1 }}></div>
            <div id="audience" style={{ height: '100%', flex: 0 }}></div>
          </div>
          {/* <div className="video-btn">
            <div
              className="btn"
              onClick={() => {
                change_Audiostatus(!audiostatus);
              }}
              onMouseEnter={() => setAudioColor(true)}
              onMouseLeave={() => setAudioColor(false)}
            >
              <img
                src={
                  audiostatus
                    ? !audioColor
                      ? '/icons/audio.png'
                      : '/icons/audio_b.png'
                    : !audioColor
                    ? '/icons/audio_x.png'
                    : '/icons/audio_x_b.png'
                }
                alt=""
              />
              <span>{audiostatus ? '静音' : '取消静音'}</span>
            </div>
            <div
              className="btn"
              onClick={() => {
                change_Videostatus(!videostatus);
              }}
              onMouseEnter={() => setVideoColor(true)}
              onMouseLeave={() => setVideoColor(false)}
            >
              <img
                src={
                  videostatus
                    ? !videoColor
                      ? '/icons/camera.png'
                      : '/icons/camera_b.png'
                    : !videoColor
                    ? '/icons/camera_x.png'
                    : '/icons/camera_x_b.png'
                }
                alt=""
              />
              <span>{videostatus ? '关闭摄像头' : '开启摄像头'}</span>
            </div>
          </div> */}
        </div>
        <div className="content_right">
          <div className="action">
            <div className="title">互动人员</div>
            <div className="action_list">
              {actionList.length > 0 ? (
                Array.from(actionList).map((item: any, index: number) => (
                  <div
                    key={index}
                    style={{
                      display: 'flex',
                      height: '64px',
                      alignItems: 'center',
                      //   marginBottom: '10px',
                    }}
                  >
                    <div className="avatar">
                      <img
                        style={{ width: '44px', height: '44px', borderRadius: '50%' }}
                        src={item.head_img ? item.head_img : '/head_img.svg'}
                        alt=""
                      />
                    </div>
                    <div
                      style={{
                        display: 'flex',
                        flexDirection: 'column',
                        justifyContent: 'center',
                        height: '64px',
                      }}
                    >
                      <div
                        className="info"
                        style={{ display: 'flex', justifyContent: 'space-between' }}
                      >
                        <div className="name">{item.username}</div>
                        <div
                          className="status"
                          style={{ color: item.actionStatus === 0 ? '#BFBFBF' : '#09CF66' }}
                        >
                          {item.actionStatus === 0 ? '• 离线' : '• 在线'}
                        </div>
                      </div>
                      <div className="positional">{item.platform_name}</div>
                    </div>
                  </div>
                ))
              ) : (
                <p
                  style={{
                    marginTop: '50px',
                    textAlign: 'center',
                    color: 'rgba(0, 0, 0, 0.5)',
                  }}
                >
                  暂无互动人员~
                </p>
              )}
            </div>
          </div>
          <div className="chat">
            <div className="title">聊天室</div>
            <ul
              id="chatList"
              style={{
                overflow: 'scroll',
                overflowX: 'hidden',
                scrollBehavior: 'smooth',
              }}
            >
              {chatList.length > 0 ? (
                chatList.map((item: any, index: number) => (
                  <li key={index}>
                    <div
                      style={{
                        display: 'flex',
                        justifyContent: 'flex-start',
                        alignItems: 'center',
                        marginTop: '12px',
                      }}
                    >
                      <div>
                        <img
                          style={{
                            width: '30px',
                            height: '30px',
                            borderRadius: '50%',
                            marginRight: '10px',
                          }}
                          src={item.head_img ? item.head_img : '/head_img.svg'}
                          alt=""
                        />
                      </div>
                      <div
                        style={{
                          fontSize: '14px',
                          fontFamily: 'PingFangSC, PingFang SC',
                          fontWeight: 400,
                          color: '#95969F',
                          lineHeight: '20px',
                        }}
                      >
                        {item.username}
                      </div>
                    </div>
                    <div
                      style={{
                        marginTop: '10px',
                        fontSize: '14px',
                        fontFamily: 'PingFangSC, PingFang SC',
                        fontWeight: 400,
                        color: '#17172A',
                        lineHeight: '20px',
                      }}
                    >
                      {item.text}
                    </div>
                  </li>
                ))
              ) : (
                <p
                  style={{
                    marginTop: '50px',
                    paddingBottom: '50px',
                    textAlign: 'center',
                    color: 'rgba(0, 0, 0, 0.5)',
                  }}
                >
                  还没有聊天内容，快来互动吧~
                </p>
              )}
            </ul>
            <div className="input">
              <TextArea
                showCount
                maxLength={100}
                onChange={onChange}
                value={chatMessage}
                placeholder="与大家互动一下~"
                style={{ height: 112, resize: 'none', background: '#F4F4F6', borderRadius: '4px' }}
                bordered={false}
              />
              <button
                onClick={() => sendChatMessage()}
                style={{
                  backgroundColor:
                    chatMessage.replace(/^\s\s*/, '').replace(/\s\s*$/, '') !== ''
                      ? '#0062FF'
                      : '#BFBFBF',
                }}
              >
                发送
              </button>
            </div>
          </div>
        </div>
      </div>
      <Modal
        title="上麦确认"
        open={upStatus}
        onCancel={() => setUpStatus(false)}
        destroyOnClose={true}
        maskClosable={false}
        closeIcon={false}
        footer={null}
        width={450}
      >
        <Divider />
        {camera.length !== 0 ? (
          <ProForm
            onFinish={(value) => start_broadcast(value)}
            submitter={{
              searchConfig: {
                submitText: '确定',
                resetText: '拒绝',
              },
              resetButtonProps: {
                style: {
                  // 隐藏重置按钮
                  display: 'none',
                },
              },
              submitButtonProps: {
                style: {
                  display: 'block',
                  position: 'absolute',
                  left: '80%',
                },
              },
            }}
          >
            <ProFormSelect
              label="摄像设备"
              name="camera"
              rules={[
                {
                  required: true,
                  message: '请选择摄像设备',
                },
              ]}
              placeholder="请选择摄像设备"
              allowClear
              request={() => getCameras()}
            ></ProFormSelect>
            <br />
          </ProForm>
        ) : (
          ''
        )}
        <br />
      </Modal>
    </div>
  );
};
export default Broadcast_audience_index;
